package com.gk.service.impl;

import cn.hutool.Hutool;
import cn.hutool.core.lang.ObjectId;
import cn.hutool.core.lang.UUID;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.eight.pojo.TbOrder;
import com.eight.pojo.UserCharge;
import com.eight.util.*;
import com.eight.vo.*;
import com.github.wxpay.sdk.WXPayUtil;
import com.gk.dao.UserChargeDao;
import com.gk.fein.ChangeRabbitFergn;
import com.gk.service.UserChargeService;
import com.gk.uitl.GetZFBNative;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import static com.gk.config.AliPayConfig.*;

/**
 * @Description: TODO
 * @Author: Van.Planifolia
 * @CreateTime: 2023-03-03  18:44
 * @Version: 1.0
 */
@Service("userChargeService")
public class UserChargeServiceImpl extends ServiceImpl<UserChargeDao, UserCharge> implements UserChargeService {
    @Autowired
    private UserChargeDao userChargeDao;
    @Value("${weixin.appid}")
    private String appid;
    @Value("${weixin.mch_id}")
    private String mchid;
    @Value("${weixin.api_key}")
    private String apiKey;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    @Autowired
    private   ChangeRabbitFergn changeRabbitFergn;
    /**
     * 根据当前登录的用户信息来进行查询用户重置记录
     *
     * @return 查询的信息
     */
    @Override
    public ComResult getUserCharge(Integer pageIndex, Integer pageSize) {
        // 拿token
        String accountToken = WebUtil.getRequest().getHeader("token");
        Map<String, Object> tokenMap = JWTTool.analyzeToken(accountToken);
        String username = (String) tokenMap.get("username");
        Page<UserCharge> page = new Page<>(pageIndex,pageSize);
        // 查数据
        page = userChargeDao.selectPage(page,new QueryWrapper<UserCharge>().eq("uname", username));
        System.out.println(page.getRecords());
        return new ComResult(2000,"查询成功",page);
    }

    /**
     * 生产付款二维码信息
     * @param weChatPay 订单对象
     * @return 生产的结果
     */
    @Override
    public ComResult createNative(WeChatPay weChatPay) {
        // 生成随机订单号
        String next = ObjectId.next();
        try {
            // 生产微信订单与二维码
            WeChatComData weChatComData = WeChatPayUtil.makePayOrder(new WeChatComData().setAmount(weChatPay.getAmount())
                    .setTitle(weChatPay.getTitle())
                    .setSerialNumber(next)

            );
            // 如果确实成功生产完毕了，我们就保存订单以及返回二维码
            if (weChatComData!=null){
                UserCharge userCharge = new UserCharge();
                userCharge.setCreatetime(TimeUtil.now(""));
                userCharge.setUcamount(weChatComData.getAmount());
                userCharge.setSerilcode(weChatComData.getSerialNumber());
                userCharge.setUname(weChatPay.getName());
                userCharge.setState(0);
                userCharge.setZid(0);
                userChargeDao.insert(userCharge);
                changeRabbitFergn.makeChargeOrder(userCharge.getSerilcode());
                return new ComResult(2000,"生产二维码成功！",weChatComData);
            }

        }catch (Exception e){
            e.printStackTrace();
        }
        return new ComResult(5000,"订单失效",null);
    }


    /**
     * 根据订单号查询订单状态
     * @param id id
     * @return
     */
    @Override
    @Transactional
    public ComResult getPayStatus(String id) {
        Map<String,String> params=new HashMap<>();
        params.put("appid",appid);
        params.put("mch_id",mchid);
        params.put("out_trade_no",id);
        params.put("nonce_str", WXPayUtil.generateNonceStr());
        try {
            HttpClient httpClient = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");
            httpClient.setHttps(true);
            httpClient.setXmlParam(WXPayUtil.generateSignedXml(params, apiKey));

            httpClient.post();
            String content = httpClient.getContent();

            Map<String, String> map = WXPayUtil.xmlToMap(content);
            if(map.get("trade_state").equals("SUCCESS")){
                //1.修改订单状态
                UserCharge userCharge = new UserCharge();
                userCharge.setState(1);
                QueryWrapper<UserCharge> wrapper=new QueryWrapper<>();
                wrapper.eq("serilcode",id);
                wrapper.eq("state",0);
                userChargeDao.update(userCharge,wrapper);
                stringRedisTemplate.opsForValue().set(id,"流水号");
                return new ComResult(2000,"支付成功",null);
            }

        }catch (Exception e){
            e.printStackTrace();
        }
        return new ComResult(5000,"支付失败",null);
    }

    /**
     * 根据id查询账单信息
     * @param id id
     * @return
     */
    @Override
    public UserCharge selectOneUserCharge(Integer id) {
        return userChargeDao.selectById(id);
    }

    /**
     * 根据账单号修改状态
     * @param serilcode 账单号
     * @return 1
     */
    @Override
    public int upStatus(String serilcode,Integer statu) {
        QueryWrapper<UserCharge> wrapper = new QueryWrapper<>();
        wrapper.eq("serilcode",serilcode);
        UserCharge userCharge = new UserCharge();
        userCharge.setState(statu);
        return userChargeDao.update(userCharge, wrapper);
    }

    /**
     * 根据订单号查询订单状态
     * @param id 订购单号
     * @return 1
     */
    @Override
    public ComResult selectTwoUserCharge(String id) throws AlipayApiException {
        //根据订单号查询订单信息
        QueryWrapper<UserCharge> wrapper = new QueryWrapper<>();
        wrapper.eq("serilcode",id);
        UserCharge userCharge = userChargeDao.selectOne(wrapper);

        AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl, app_id, merchant_private_key, "json", charset, alipay_public_key, sign_type); //获得初始化的AlipayClient
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();//创建API对应的request类
        //request.putOtherTextParam("app_auth_token", "201912BXXXXXX");//授权token，代调用必传

        request.setBizContent("{" + "\"out_trade_no\":\""+id+"\"}"); //设置业务参数
        AlipayTradeQueryResponse response = alipayClient.execute(request);//通过alipayClient调用API，获得对应的response类
        String money = response.getBuyerPayAmount();
        if (!"0.00".equals(money)) {
            userCharge.setState(1);
            userChargeDao.updateById(userCharge);
            stringRedisTemplate.opsForValue().set(id,"id");
            return new ComResult(2000,"支付成功");
        }else{
            return new ComResult(5000,"支付失败");
        }
    }

    /**
     * 根据订单号生成二维码
     * @param amount 金额
     * @param uid 订单序号
     * @return 1
     */
    @Override
    public ComResult createNativeThree(Double amount, Integer uid) {
        UserCharge userCharge = userChargeDao.selectById(uid);
        OrderPayVo orderPayVo = new OrderPayVo();
        orderPayVo.setOrderNo(userCharge.getSerilcode());
        orderPayVo.setTitle("充值金额"+userCharge.getUcamount());
        orderPayVo.setUsername(userCharge.getUname());
        orderPayVo.setAmount(amount);
        //生成二维码
        GetZFBNative getZFBNative =new GetZFBNative();
        String s1 = getZFBNative.aliPay(orderPayVo);
        ErWeimaVO erWeimaVO = new ErWeimaVO();
        erWeimaVO.setUrl(s1);
        erWeimaVO.setId(orderPayVo.getOrderNo());
        if(s1!=null){
            return new ComResult(2000,"生成成功",erWeimaVO);
        }else{
            return new ComResult(5000,"生成失败");
        }

    }

    /**
     * 取消订单，修改订单状态
     * @param id 订单序号
     * @return 1
     */
    @Override
    public ComResult setPayStatus(Integer id) {
        UserCharge userCharge = userChargeDao.selectById(id);
        userCharge.setState(3);
        int i = userChargeDao.updateById(userCharge);
        if(i>0){
            return  new ComResult(2000,"取消订单成功");
        }else{
            return  new ComResult(5000,"取消订单失败");
        }
    }
}
